package com.hb.B_面向对象.J_lambda和集合.B_集合的高阶函数API

import java.util.*

/**
 * 求和的方式： sumBy,sum,fold,reduce
 *  对集合进行求和操作是十分常见的操作。比如我们要得到该列表中学生的平均分就需要
 *  先计算出所有学生的总分。
 *
 *  sum：对数组类型的列表进行求和，sum与sumBy类似，但是sum只能对一些数值类型的列表进行求和
 *
 *  fold:
 *   public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R
 *  fold方法需要接受两个参数，第一个参数initial通常称为初始化值，第二个参数为operation函数。在实现的时候，
 *  通过for语句来遍历集合中的每个元素，每次都会调用operation函数，而该函数的参数有两个，一个是上一次调用该函数的结果
 *  （如果是第一次调用operation函数，则传入初始化值initial）,另外一个则是当前遍历到的集合元素。简单来说就是每次都调用
 *  operation函数，然后将产生的结果作为参数提供给下一次调用。
 *
 *  fold很好的利用了递归的思想。
 *
 *  reduce:
 *      reduce方法和fold非常相似，唯一的区别就是reduce方法没有初始值。
 * public inline fun <S, T : S> Iterable<T>.reduce(operation: (acc: S, T) -> S): S
 *
 * reduce方法只接收一个参数，该参数为一个函数。
 */
fun main() {

    val student1 = Student("student1", 30, "男", 85)
    val student2 = Student("student2", 20, "男", 80)
    val student3 = Student("student3", 25, "女", 82)
    val student4 = Student("student4", 28, "女", 80)
    val student5 = Student("student5", 35, "男", 89)

    var studentList = listOf<Student>(student1, student2, student3, student4, student5)

    var scoreSum=studentList.sumBy {
        it.score
    }
    println(scoreSum)

    val list = listOf<Int>(1, 2, 3, 4, 5)
    val listSum = list.sum()
    println(listSum)

    //fold
    val scoreSum2=studentList.fold(0){
        sum,student->sum+student.score
    }
    println(scoreSum2)

    //reduce
    /**
     * 当要遍历的集合为空时，会抛出一个异常。因为没有初始值，所以
     * 初始值默认是集合中的第一个元素
     */
//    studentList.reduce{
//
//    }


}